<template>
    <div class="map">
        <div id="map" class="map-container"></div>
        <div class="title">
            <div class="ip_address">{{ address }}</div>
            <!-- 搜索框:有搜索图标 -->
            <el-input
                v-model="searchContent"
                placeholder="请输入城市名称"
                @keyup.enter="handleSearch"
            >
                <template #prefix>
                    <el-icon>
                        <Search />
                    </el-icon>
                </template>
            </el-input>
            <!-- 下拉框 -->
            <el-select v-model="shape" placeholder="选择绘制图形">
                <el-option value="绘制线" @click="handleDrawType"
                    >绘制线</el-option
                >
                <el-option value="绘制矩形" @click="handleDrawType"
                    >绘制矩形</el-option
                >
                <el-option value="绘制多边形" @click="handleDrawType"
                    >绘制多边形</el-option
                >
                <el-option value="绘制圆形" @click="handleDrawType"
                    >绘制圆形</el-option
                ><el-option value="自由绘制" @click="handleDrawType"
                    >自由绘制</el-option
                >
                <el-option value="退出绘制" @click="handleDrawType"
                    >退出绘制</el-option
                >
            </el-select>
            <el-select
                v-model="mark"
                placeholder="选择标记类型"
                @click="isClick"
                :disabled="isDisabled"
            >
                <el-option value="充电站" @click="handleMarker"
                    >充电站</el-option
                >
                <el-option value="公交站" @click="handleMarker"
                    >公交站</el-option
                >
                <el-option value="停车点" @click="handleMarker"
                    >停车点</el-option
                >
                <el-option value="退出标记" @click="handleMarker"
                    >退出标记</el-option
                >
            </el-select>
        </div>
        <div class="overlay" ref="refOverLay"></div>
    </div>
</template>

<script setup>
import { onMounted, ref } from "vue"; // 确保 DOM 加载完成
import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import { Search } from "@element-plus/icons-vue";
import { getCityByIp, searchCity, getAdcodeByCity } from "/src/api/getData";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import GeoJSON from "ol/format/GeoJSON";
import Style from "ol/style/Style";
import Fill from "ol/style/Fill";
import Stroke from "ol/style/Stroke";
import Draw from "ol/interaction/Draw.js";
import { easeOut } from "ol/easing";
import Point from "ol/geom/Point.js";
import Icon from "ol/style/Icon";
import Circle from "ol/style/Circle";
import Text from "ol/style/Text";
import parkingIcon from "/src/assets/停车（点击）.png";
import powerIcon from "/src/assets/充电站.png";
import busIcon from "/src/assets/公交站点.png";
import Feature from "ol/Feature";
import { Cluster } from "ol/source";
import Overlay from "ol/Overlay";
import { ElMessage } from "element-plus";
import { fa } from "element-plus/es/locale/index.mjs";

const address = ref("");
const adcode = ref("");
const searchContent = ref("");
const shape = ref("");
const mark = ref("");
const refOverLay = ref(null);
const map = ref(null);
const layerChina = ref(null);
const markerLayer = ref(null);
// 定义经纬度
const centerPoint = ref([114.21, 30.52]);
const tianMap2 = ref(null);
const drawLayer = ref(null);
let handleClick = null;
const isDisabled = ref(false)

const isClick = () => {
    if (map.value.getView().getZoom() < 13) {
        ElMessage.warning("请缩放地图到13级及以上！");
        isDisabled.value = true;
        console.log(isDisabled);
        console.log(map.value.getView().getZoom());
    } else {
        isDisabled.value = false;
        console.log(isDisabled);
    }
};
onMounted(() => {
    tianMap2.value = new TileLayer({
        source: new XYZ({
            url: "http://t0.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=b8ec3c2fd9ce8aa502d09b36061fe9d4",
            wrapX: false,
        }),
    });

    drawLayer.value = new VectorLayer({
        source: new VectorSource({}),
        style: (feature) => {
            const geometryType = feature.getGeometry().getType();
            if (geometryType == "Polygon" || geometryType == "Circle") {
                return new Style({
                    fill: new Fill({
                        color: "rgba(128,0,128,0.5)",
                    }),
                    stroke: new Stroke({
                        color: "#0099ff",
                        width: 2,
                    }),
                });
            } else {
                return new Style({
                    stroke: new Stroke({
                        color: "#0099ff",
                    }),
                });
            }
        },
    });
    markerLayer.value = new VectorLayer({
        source: new VectorSource({}),
    });

    map.value = new Map({
        target: "map",
        view: new View({
            center: [100, 30],
            projection: "EPSG:4326",
            zoom: 4,
        }),
        layers: [
            new TileLayer({
                source: new XYZ({
                    url: "http://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=b8ec3c2fd9ce8aa502d09b36061fe9d4",
                    wrapX: false,
                }),
            }),
        ],
    });

    map.value.addLayer(tianMap2.value);
    map.value.addLayer(drawLayer.value);
    map.value.addLayer(markerLayer.value);
    // 获取经纬度
    getCityByIp().then((res) => {
        address.value = res.city;
        adcode.value = res.adcode;
        getAdcodeByCity(res.city).then((res) => {
            centerPoint.value = res.location.split(",").map(Number);
            addSearchArea(
                `https://geo.datav.aliyun.com/areas_v3/bound/${adcode.value}_full.json`
            );
        });
    });
    map.value.getView().animate({
        center: centerPoint.value,
        zoom: 10,
        duration: 2000,
    });

    let overlay = new Overlay({
        element: refOverLay.value,
    });
    map.value.addOverlay(overlay);
    map.value.on("click", (e) => {
        let coordinate = e.coordinate;
        let fea = layerChina.value
            .getSource()
            .getFeaturesAtCoordinate(coordinate)[0];
        if (fea) {
            let name = fea.get("name");
            let lon = fea.get("center")[0];
            let lan = fea.get("center")[1];
            let center = fea.get("center");
            refOverLay.value.innerHTML = `
              <div>当前位置为：${name}</div>
              <div>经度：${lon}</div>
              <div>纬度：${lan}</div>
            `;

            overlay.setPosition(center);
        } else {
            overlay.setPosition(undefined);
        }
    });
});
const handleSearch = () => {
    if (searchContent.value.trim()) {
        searchCity(searchContent.value).then((res) => {
            adcode.value = res[0].adcode;
            // 先把layerChina.value设置为null
            if (layerChina.value) {
                map.value.removeLayer(layerChina.value);
            }
            getAdcodeByCity(res[0].name).then((res) => {
                centerPoint.value = res.location.split(",").map(Number);
                addSearchArea(
                    `https://geo.datav.aliyun.com/areas_v3/bound/${adcode.value}_full.json`
                );
                map.value.getView().setCenter(centerPoint.value);
            });
        });
    }
};
const draw = (type) => {
    const typeMap = {
        绘制线: "LineString",
        绘制矩形: "Polygon",
        绘制多边形: "Polygon",
        绘制圆形: "Circle",
        自由绘制: "LineString",
        退出绘制: null,
    };
    if (typeMap[type]) {
        let drawShape;
        if (typeMap[type] == "Polygon" || typeMap[type] == "Circle") {
            drawShape = new Draw({
                type: typeMap[type],
                source: drawLayer.value.getSource(),
                style: new Style({
                    fill: new Fill({
                        color: "rgba(128,0,128,0.5)",
                    }),
                    stroke: new Stroke({
                        color: "#0099ff",
                        width: 4,
                    }),
                }),
            });
            console.log(typeMap[type]);
        } else {
            drawShape = new Draw({
                type: typeMap[type],
                source: drawLayer.value.getSource(),
                freehand: type == "自由绘制",
            });
        }
        map.value.addInteraction(drawShape);
    } else {
        map.value.getInteractions().forEach((interaction) => {
            if (interaction instanceof Draw) {
                map.value.removeInteraction(interaction);
            }
        });
        drawLayer.value.getSource().clear();
    }
};
const addSearchArea = (url) => {
    layerChina.value = new VectorLayer({
        source: new VectorSource({
            url: url,
            format: new GeoJSON(),
        }),
        style: new Style({
            fill: new Fill({
                color: "rgba(255, 0, 0, 0.5)",
            }),
            stroke: new Stroke({
                color: "black",
                width: 2,
            }),
        }),
        minZoom: 5,
        maxZoom: 10,
    });
    map.value.addLayer(layerChina.value);
};
const handleDrawType = () => {
    map.value.getInteractions().forEach((interaction) => {
        if (interaction instanceof Draw) {
            map.value.removeInteraction(interaction);
        }
    });
    draw(shape.value);
};
const handleMarker = (e) => {
    if (handleClick) {
        map.value.un("click", handleClick);
        handleClick = null;
    }
    const typeIcon = {
        充电站: powerIcon,
        公交站: busIcon,
        停车点: parkingIcon,
        退出标记: null,
    };
    const matchStyle = (mark) => {
        return new Style({
            image: new Icon({
                src: mark,
                scale: 0.5,
            }),
        });
    };

    if (!typeIcon[mark.value]) {
        return;
    }

    handleClick = (e) => {
        const coordinate = e.coordinate;
        const point = new Feature({
            geometry: new Point(coordinate),
            type: mark.value,
        });
        point.setStyle(matchStyle(typeIcon[mark.value]));
        markerLayer.value.getSource().addFeature(point);
    };

    map.value.on("click", handleClick);
    clusterByZoom();
};

const clusterByZoom = () => {
    // 创建聚类数据源
    if (!markerLayer.value || !markerLayer.value.getSource()) {
        return;
    }
    let source = markerLayer.value.getSource();
    const cluseteSource = new Cluster({
        source: source,
        distance: 20,
    });

    const matchColor = {
        充电站: "rgba(255,0,0,0.5)",
        公交站: "rgba(0,255,0,0.5)",
        停车点: "rgba(0,0,255,0.5)",
    };

    // 创建聚类图层
    const clusterLayer = new VectorLayer({
        source: cluseteSource,
        style: (feature) => {
            const features = feature.get("features");
            const size = features.length;
            const type = features[0].get("type");
            const color = matchColor[type];

            if (size == 1) {
                const originFeature = features[0];
                return (
                    originFeature.getStyle() ||
                    markerLayer.value.getStyleFunction()(originFeature)
                );
            }

            return new Style({
                image: new Circle({
                    radius: 15,
                    fill: new Fill({
                        color: color,
                    }),
                }),
                text: new Text({
                    text: size.toString(),
                    fill: new Fill({ color: "white" }),
                }),
            });
        },
    });

    // 移除旧的聚类图层
    map.value.getLayers().forEach((layer) => {
        if (layer.get("type") == "cluster") {
            map.value.removeLayer(layer);
        }
    });

    // 添加最新聚类图层
    clusterLayer.set("type", "cluster");
    map.value.addLayer(clusterLayer);
    console.log("我正在缩放");
};
</script>

<style scoped>
.map-container {
    width: 100%;
    height: calc(100% - 100px);
    border: 1px solid #ccc;
    position: fixed;
    top: 100px;
    left: 0;
    right: 0;
    bottom: 0;
}
.btn {
    position: absolute;
    top: 80px;
    left: 20px;
    display: flex;
    gap: 10px;
}
.title {
    position: fixed;
    top: 0px;
    left: 0px;
    right: 0px;
    width: 100%;
    height: 100px;
    background-color: #0099ff;
    display: flex;
    justify-content: space-around;
    align-items: center;
}
.el-input,
.el-select {
    width: 250px;
}
/* el-select__wrapper el-tooltip__trigger el-tooltip__trigger使用深度选择器修改padding */
::v-deep(.el-select__wrapper) {
    padding: 15px 15px;
}
::v-deep(.el-input__wrapper) {
    padding: 5px 15px;
}
.ip_address {
    color: #fff;
    font-size: 20px;
}
.overlay {
    padding: 20px 15px;
    background: pink;
    border-radius: 10px;
    box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
}
</style>
